package com.aliengen.thingple.thingple.api;

import com.aliengen.thingple.thingple.api.exception.APICallException;
import com.aliengen.thingple.thingple.api.exception.FieldNotFoundException;
import com.aliengen.thingple.thingple.api.models.Operator;
import com.aliengen.thingple.thingple.preferences.PreferencesUtil;
import com.aliengen.thingple.thingple.tag.BundleTag;
import com.aliengen.thingple.thingple.tag.CylinderTag;
import com.aliengen.thingple.thingple.tag.OperatorTag;
import com.aliengen.thingple.thingple.tag.Tag;

/**
 * This class is part of the Thingple mobile application for the CMC168 Handheld reader.
 *
 * Copyright AlienGen Limited 2016. All rights reserved.
 *
 * @author Timothé Mermet-Buffet <tim@aliengen.com>
 */
public class ThingpleAPI {
    protected OperatorTag operator_tag;
    protected String deviceId;

    protected String last_errors;

    public ThingpleAPI()
    {
        this.last_errors = "";
    }

    public String getLastErrors()
    {
        return this.last_errors;
    }

    public Boolean authenticate(OperatorTag tag, String deviceId)
    {
        if(tag.isAllowed())
        {
            System.out.println("Tag already authenticated! Bypass API Request!");
            this.operator_tag = tag;
            return true;
        }

        System.out.println("Retrieving preferences...");
        String url = PreferencesUtil.get(PreferencesUtil.SHARE_API_URL, "");
        String client_id = PreferencesUtil.get(PreferencesUtil.SHARE_API_CLIENT_ID, "");
        String client_secret = PreferencesUtil.get(PreferencesUtil.SHARE_API_CLIENT_SECRET, "");

        if(url.length() == 0)
        {
            this.last_errors = "You must set the Sync parameters in the settings!";
            return false;
        }

        System.out.println("URL: " + url);
        System.out.println("Client ID: " + client_id);
        System.out.println("Client Secret: " + client_secret);
        System.out.println("Device ID: " + deviceId);

        System.out.println("Creation of the connector...");
        ThingpleAPIConnector api = new ThingpleAPIConnector();
        api.setURL(url);
        api.setCredentials(client_id, client_secret);
        this.deviceId = deviceId;
        api.setDeviceId(deviceId);

        try {
            System.out.println("Authentication...");
            Operator operator = api.getOperator(tag.getOperatorId());
            tag.setOperator(operator);
            this.operator_tag = tag;
            System.out.println("Authentication successful!");
        } catch(APICallException e)
        {
            e.printStackTrace();
            this.last_errors = e.getMessage();
            return false;
        } catch(FieldNotFoundException e)
        {
            e.printStackTrace();
            this.last_errors = e.getMessage();
            return false;
        }

        this.operator_tag.setAllowed(true);
        return true;
    }

    public void disconnect()
    {
        this.operator_tag = null;
    }

    public Boolean isAuthenticated()
    {
        return this.operator_tag != null;
    }

    public Boolean syncCylinderTag(Tag tag) {
        /*
        if(tag.isSynchronized())
        {
            //return true;
        }*/

        String url = PreferencesUtil.get(PreferencesUtil.SHARE_API_URL, "");
        String client_id = PreferencesUtil.get(PreferencesUtil.SHARE_API_CLIENT_ID, "");
        String client_secret = PreferencesUtil.get(PreferencesUtil.SHARE_API_CLIENT_SECRET, "");

        ThingpleAPIConnector api = new ThingpleAPIConnector();
        api.setURL(url);
        api.setCredentials(client_id, client_secret);
        api.setDeviceId(this.deviceId);

        try {
            if(tag instanceof CylinderTag) {
                api.postCylinder((CylinderTag)tag, this.getOperatorId());
            }
            else
                if(tag instanceof BundleTag)
                {
                    api.postBundle((BundleTag)tag, this.getOperatorId());
                }
        } catch(APICallException e)
        {
            e.printStackTrace();
            this.last_errors = e.getMessage();
            return false;
        } catch(FieldNotFoundException e)
        {
            e.printStackTrace();
            this.last_errors = e.getMessage();
            return false;
        }
        return true;
    }

    public boolean addAnomaly(CylinderTag tag, String phase_slug, String inspection_slug)
    {
        String url = PreferencesUtil.get(PreferencesUtil.SHARE_API_URL, "");
        String client_id = PreferencesUtil.get(PreferencesUtil.SHARE_API_CLIENT_ID, "");
        String client_secret = PreferencesUtil.get(PreferencesUtil.SHARE_API_CLIENT_SECRET, "");

        ThingpleAPIConnector api = new ThingpleAPIConnector();
        api.setURL(url);
        api.setCredentials(client_id, client_secret);
        api.setDeviceId(this.deviceId);

        try {
            api.addAnomaly(tag, this.getOperatorId(), phase_slug, inspection_slug);
        } catch(APICallException e)
        {
            e.printStackTrace();
            this.last_errors = e.getMessage();
            return false;
        }
        return true;
    }

    public boolean addMaintenance(CylinderTag tag, String operation_slug, Boolean maintenance_done)
    {
        String url = PreferencesUtil.get(PreferencesUtil.SHARE_API_URL, "");
        String client_id = PreferencesUtil.get(PreferencesUtil.SHARE_API_CLIENT_ID, "");
        String client_secret = PreferencesUtil.get(PreferencesUtil.SHARE_API_CLIENT_SECRET, "");

        ThingpleAPIConnector api = new ThingpleAPIConnector();
        api.setURL(url);
        api.setCredentials(client_id, client_secret);
        api.setDeviceId(this.deviceId);

        try {
            api.addMaintenance(tag, this.getOperatorId(), operation_slug, maintenance_done);
        } catch(APICallException e)
        {
            e.printStackTrace();
            this.last_errors = e.getMessage();
            return false;
        }
        return true;
    }

    public String getOperatorName()
    {
        return this.operator_tag.getOperator().firstname + " " + this.operator_tag.getOperator().lastname;
    }

    public OperatorTag getOperatorTag()
    {
        return this.operator_tag;
    }

    public int getOperatorId()
    {
        return this.operator_tag.getOperatorId();
    }
}
